package com.contory.ssn_lgnd.app.maingame;

import java.util.LinkedList;

import android.util.FloatMath;
import android.util.Log;

import com.contory.ssn_lgnd.app.Assets;
import com.contory.ssn_lgnd.app.comp.DrawPtr;
import com.contory.ssn_lgnd.app.comp.UpdatePtr;
import com.contory.ssn_lgnd.app.comp.ViewObject;
import com.contory.ssn_lgnd.framework.gl.SpriteBatcher;
import com.contory.ssn_lgnd.framework.gl.Texture;
import com.contory.ssn_lgnd.framework.math.OverlapTester;
import com.contory.ssn_lgnd.framework.math.Polygon;
import com.contory.ssn_lgnd.framework.math.PolygonResult;
import com.contory.ssn_lgnd.framework.math.Vector2;

public class PRedBullet extends BulletObjectPtr{
	Vector2 nDir;
	boolean enableBool = false;
	final ColiObjPtr target;
	int bulletDamage = 100;
	
	//add property
	private static float velocityScala = 5.0f; //5.0
	private static final float VIEW_WIDTH = 0.5f;
	private static final float VIEW_HEIGHT = 0.25f;
	ViewObject view;
	float rot = 0.0f;
	Polygon coliBound;
	Vector2 velocity;
	
	final ParticleEffect ptcEft;
	final ColisionManager cm;
	
	TextureEffect effect;
	
	byte state = 0;
	public PRedBullet(float strX, float strY, ColisionManager cm, ColiObjPtr target, ParticleEffect ptcEft){
		nDir = new Vector2();
		velocity = new Vector2();
		view = new ViewObject();
		view.setXY_WH_TR(strX, strY, VIEW_WIDTH, VIEW_HEIGHT, Assets.tex_reg_redBullet);
		coliBound = new Polygon();
		coliBound.lockAddPoint(VIEW_WIDTH, VIEW_HEIGHT);
		coliBound.addPoint(1, 1);
		coliBound.addPoint(0, 1);
		coliBound.addPoint(0, 0);
		coliBound.addPoint(1, 0);
		coliBound.unLockAddPoint();
		effect = new TextureEffect(0, 0, 1, 1, Assets.TEX_REG_SMALL_EXPLOSION);
		this.cm = cm;
		this.target = target;
		enableBool = true;
		state = 0;
		this.ptcEft = ptcEft;
		ptcEft.setInit();
		//ptcEft.setEnable();
	}
	
	public boolean getEnabled(){
		return enableBool;
	}

	@Override
	public void draw(SpriteBatcher batcher) {
		if(!enableBool){
			return;
		}
		switch(state){
			case 0:
			batcher.drawSprite(view.x, view.y, view.w, view.h, -rot, view.tr);
			break;
			
			case 1:
			effect.draw(batcher);
			break;
		}
	}

	@Override
	public void update(float deltaTime) {
		if(!enableBool){
			return;
		}
		switch(state){
			case 0:
			updateNomalDir(deltaTime);
			updateViewPos(deltaTime);
			setViewDir(nDir.x);
			updateRot(nDir);
			updateBound();
			updateCollision();
			updateTarget();
			updatePtcEffect();
			break;
			
			case 1:
			updateEffect(deltaTime);
			break;
			
			case 2:
			break;
		}
	}
	
	private void updateTarget(){
		if(!target.getEnableBool()){
			state = 1;
			effect.setInit(view.x, view.y);
		}
	}
	
	private void updateEffect(float deltaTime){
		effect.update(deltaTime);
		if(!effect.getEffectBool()){
			enableBool = false;
			state = 2;
		}
	}
	
	private void updatePtcEffect(){
		ptcEft.makeParticle(-nDir.x, -nDir.y, view.x, view.y);
	}
	
	private void updateCollision(){
		if(OverlapTester.overlapPolygons(this.coliBound, target.getColiBound())){
			state = 1;
			ptcEft.setDisable();
			effect.setInit(view.x, view.y);
			target.setEnergy(-bulletDamage);
		}

		LinkedList<ColiObjPtr> coliStaticListPtr = cm.getStaticObjList();
		for (ColiObjPtr coliObjPtr : coliStaticListPtr) {
			if(coliObjPtr.getID() == TerrainParts.ID){
				if(OverlapTester.overlapPolygons(this.coliBound, coliObjPtr.getColiBound())){
					state = 1;
					ptcEft.setDisable();
					effect.setInit(view.x, view.y);
					break;
				}	
			}
		}
	}
	
	private void updateViewPos(float deltaTime){
		view.x += velocity.x;
		view.y += velocity.y;
	}
	
	private void updateBound(){
		coliBound.setPos(view.x, view.y);
		coliBound.setRot(rot);
	}
	
	private void updateRot(Vector2 nDir){
		float xAbs = Math.abs(nDir.x);
		rot = (float)Math.acos(xAbs);
		if(nDir.x >=0){
			if(nDir.y >= 0)
				rot = -rot;
		}
		else{
			if(nDir.y <0)
				rot = -rot;
		}
	}
	
	private void setViewDir(float dirX){
		if(dirX >= 0){
			view.w = VIEW_WIDTH;
		}
		else{
			view.w = -VIEW_WIDTH;
		}
	}
	
	private void updateNomalDir(float deltaTime){
		if(target == null)
			return;
		nDir.set(target.getPosX() - view.x, target.getPosY() - view.y);
		nDir.nor();
		velocity.set(nDir.x * velocityScala * deltaTime, nDir.y * velocityScala * deltaTime);
	}
}
